﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace peonwar
{
    public enum Power
    {
        EnergyDrainer,
        Heal,
        Bombe,
        Cresus,
        SuperPeon,
        Random,
    }

    public class User
    {
        // ---CONSTRUCTOR---
        #region constructeur
        public User(bool team, string n, Game g)
        {
            game = g;
            Name = n;
            TeamBlue = team;
            Cooldown = 100;
            cooldownBonus = 0;

            PeonList = new List<Unit>();
            PeonBuffer = new Queue<Unit>();
            PeonBufferDisplay = new List<Sprite>();
            chrono = new Timer(60);
            BaseHealthLevel = 1;
            ProductionLevel = 1;
            IncomeLevel = 1;
            Dead = false;
            IsBleeding = false;
            BleedTicks = 0;
            Level = 0;
            Experience = 0;
            isIA = false;
            IsLaunchingBomb = false;
            DelayAfterLaunching = 0;
            BombSeed = 0;
            IncomeBonus = 0;
            Income = 0;
            CanSpawn = true;
            if (TeamBlue)
                TeamColor = Color.Blue;
            else
                TeamColor = Color.Red;

            AvailableUnits = new bool[9];
            for (int b = 0; b < AvailableUnits.Length; b++)
                AvailableUnits[b] = true;
            Available = new bool[] { true, true, true, false, false, false, false, false, false };
            AvailableCost = new int[] { 50, 50, 50, 80, 80, 80, 140, 180, 240 };
            CanUpGrade = new bool[,] { { true, true, true, true }, { true, true, true, true }, { true, true, true, true } };
            //                              LIGHT                         MEDIUM                  HEAVY
            Cost = new int[,] { { 75, 75, 75, 75 }, { 100, 100, 100, 100 }, { 125, 125, 125, 125 } };
            //                           pow acc   res  speed
            // [type d'uniter, type d'amelioration]
            UnitCost = new int[] { 20, 30, 30, 50, 50, 50, 90, 120, 200 };

            Energy = new int[] { 10, 40, 30, 55, 55, 55, 75, 80, 100, 100 };

            //Recherches
            ResearchTree = new ResearchOne(new Vector2(665, 90), GameTexture.Researchs[0], this);
            productBonus = false;
            bombBonus = false;
            baseBonus = false;
            amlBonus = false;


            if (TeamBlue)
            {
                PowersList = new ButtonTimed[]
            {
                new ButtonTimed(new Vector2(200, 20), GameTexture.EnergyButton, new Timer(60), 1),
                new ButtonTimed(new Vector2(260, 20), GameTexture.HealButton, new Timer(90), 2),
                new ButtonTimed(new Vector2(320, 20), GameTexture.BombButton, new Timer(60), 3), 
                new ButtonTimed(new Vector2(380, 20), GameTexture.GoldButton, new Timer(120), 4),
                new ButtonTimed(new Vector2(440, 20), GameTexture.SuperButton, new Timer(150), 5), 
                new ButtonTimed(new Vector2(500, 20), GameTexture.RandButton, new Timer(60), 6), 
            };
            }
            else
            {
                PowersList = new ButtonTimed[]
            {
                new ButtonTimed(new Vector2(500 + 550, 20), GameTexture.EnergyButton, new Timer(60), 1),
                new ButtonTimed(new Vector2(440 + 550, 20), GameTexture.HealButton, new Timer(90), 2),
                new ButtonTimed(new Vector2(380 + 550, 20), GameTexture.BombButton, new Timer(60), 3), 
                new ButtonTimed(new Vector2(320 + 550, 20), GameTexture.GoldButton, new Timer(180), 4),
                new ButtonTimed(new Vector2(260 + 550, 20), GameTexture.SuperButton, new Timer(180), 5), 
                new ButtonTimed(new Vector2(200 + 550, 20), GameTexture.RandButton, new Timer(90), 6), 
            };
            }
        }
        #endregion

        // ---PROPERTIES---
        #region propriétés
        public Game game;
        public PlayerType Type;
        public ButtonTimed[] PowersList;
        public bool[] AvailableUnits;
        private int b;
        public int Bank
        {
            get
            {
                return b;
            }
            set
            {
                if (value < 0)
                    b = 0;
                else
                    b = value;
            }
        }
        public bool TeamBlue { get; set; }
        public bool Dead { get; set; }
        public bool Attacked { get; set; }
        public int BaseHealth { get; set; }
        public int MaxBaseHealth;
        public Vector2 SpawnPosition { get; set; }
        public int Level;
        public bool IsLaunchingBomb;
        public int DelayAfterLaunching;
        private int BombSeed;
        public bool finishhim;
        public int Experience
        {
            get
            {
                return xpAux;
            }
            set
            {
                if (value > 9999)
                {
                    if (Level < 5)
                    {
                        Level++;
                        if (hudassociated != null)
                        {
                            UnlockPower();
                            hudassociated.UpdateButtonUnitTextures();
                        }
                        xpAux = value - 10000;
                        if (Type == PlayerType.Player)
                        {
                            GameSound.Ting.Play();
                            Advert Adv = new Advert(new Vector2(275, 400), GameData.Font_Profil, GameData.GameString[220], 1.5f, new Vector2(0, -1), 1.0f, TeamColor, false, true);
                            User.AdvertList.Add(Adv);
                        }
                    }
                    else
                    {
                        if (Level == 5)
                        {
                            Level++;
                            if (hudassociated != null)
                            {
                                UnlockPower();
                                hudassociated.UpdateButtonUnitTextures();
                            }
                            if (Type == PlayerType.Player)
                            {
                                GameSound.Ting.Play();
                                Advert Adv = new Advert(new Vector2(275, 400), GameData.Font_Profil, GameData.GameString[220], 1.5f, new Vector2(0, -1), 1.0f, TeamColor, false, true);
                                User.AdvertList.Add(Adv);
                                AchievementManager.AchievementList[6].Add();
                            }
                        }
                        else
                        {
                            xpAux = 10000;
                        }
                    }
                }
                else
                    xpAux = value;
            }
        }
        public bool isIA;
        public bool CanSpawn;
        public Color TeamColor;
        public bool IsBleeding;
        public int BleedTicks;
        public Timer chrono;
        private Perso _charaux;
        public Perso character
        {
            get
            {
                return _charaux;
            }
            set
            {
                if (value == Perso.Frika)
                    cooldownBonus += 0.3;
                _charaux = value;
            }
        }


        // Ameliorations du joueur, index de chaque tableaux de 0 a 2 pour leger, medium ou heavy
        public int[] TechPower = new int[] { 1, 1, 1 };
        public int[] TechAccuracy = new int[] { 1, 1, 1 };
        public int[] TechResist = new int[] { 1, 1, 1 };
        public int[] TechSpeed = new int[] { 1, 1, 1 };

        // Stats des unitees
        public double[] UnitPower = new double[] { 600, 220, 40, 200, 90, 600, 165, 400, 300 };
        public double[] UnitAccuracy = new double[] { 200, 40, 32, 80, 68, 200, 100, 200, 160 };
        public double[] UnitResist = new double[] { 0, 0, 0 };
        public double[] UnitSpeed = new double[] { 0.8, 0.7, 0.7, 0.7, 0.7, 0.7, 1.0, 0.4, 0.5 };
        public double[] UnitMaxHealth = new double[] { 460, 400, 500, 620, 550, 450, 700, 800, 1000 };
        public DamageType[] UnitAtkType = new DamageType[] { DamageType.Sliced, DamageType.Projectile, DamageType.Projectile, DamageType.Projectile, DamageType.Projectile, DamageType.Explosif, DamageType.Projectile, DamageType.Explosif, DamageType.Projectile };
        public int[] UnitRange = new int[] { 45, 250, 160, 160, 220, 200, 120, 201, 120 };
        public int[] UnitTick = new int[] { -1, -1, 5, -1, 8, -1, 5, -1, 3 };
        public int[] UnitprojeResist = new int[] { 5, 25, 25, 30, 40, 15, 60, 80, 85 };
        public int[] UnitexploResist = new int[] { 5, 25, 25, 60, 30, 30, 5, 35, 60 };
        public int[] UnitsliceResist = new int[] { 5, 5, 5, 45, 20, 10, 90, 100, 100 };

        public int BaseHealthLevel;
        public int ProductionLevel;
        public int IncomeLevel;
        public int IncomeBonus;
        public int Income;

        // Infos sur les debloquages du joueur
        public Boolean[,] CanUpGrade; // Peut upgrader
        public Boolean[] Available; // Liste des peons disponibles
        public int[] AvailableCost; // Liste des couts des debloquages des peons
        public int[,] Cost;
        public int[] Energy;
        public int[] UnitCost;

        // Cooldown (temps entre la creation des peons)
        public double Cooldown { get; set; }
        public double cooldownBonus;

        // Liste
        public List<Unit> PeonList { get; set; } // Des peons (propre a chaque user)
        public Queue<Unit> PeonBuffer { get; set; } // Buffer a peon
        public List<Sprite> PeonBufferDisplay { get; set; } // Sprite d'affichage du buffer
        public static List<AnimatedEffect> EffectList = new List<AnimatedEffect>(); // Des effets
        public static List<Advert> AdvertList; // Liste d'advert
        public static List<Achievert> AchievertList; // Liste d'achievert

        int xpAux;
        public string Name;
        public Hud hudassociated;

        public Research ResearchTree { get; private set; }
        public bool productBonus;
        public bool bombBonus;
        public bool baseBonus;
        public bool amlBonus;
        #endregion

        // ---METHODES---
        #region update
        public void UpDate()
        {
            if (Cooldown < 100)
                Cooldown += 0.2 + cooldownBonus;

            if (chrono.UpdateTimer())
            {
                chrono.RestartTimer();

                Tools.BankManage(this, Income == 0 ? 100 * IncomeLevel + IncomeBonus : Income);
                /*
                if (isIA)
                {
                    for (int j = 0; j < 3; j++)
                        Console.WriteLine("Attaque {0}, Accuracy {1}, Resistance {2}, Vitesse {3}", TechPower[j], TechAccuracy[j], TechResist[j], TechSpeed[j]);
                    Console.WriteLine("----------------------------------------------------");
                    Console.WriteLine("Income level {0}, Production level {1}", IncomeLevel, ProductionLevel);
                    Console.WriteLine("Bank = " + Bank);

                }*/
            }

            if (IsBleeding)
            {
                if (BleedTicks == 0)
                    IsBleeding = false;
                BleedTicks++;
                BleedTicks = BleedTicks % 5;
            }

            if (character == Perso.Doktor)
                DoktorPower();
        }

        public void UpdatePeon(GameTime gameTime, int ticks, User opponent)
        {
            for (int index1 = 0; index1 < this.PeonList.Count; index1++)
            {
                Unit unit = this.PeonList[index1];
                unit.UpDate(gameTime, this, opponent, index1, ticks);
                // Retire les peons mort depuis longtemps (les corps en putrefaction)
                if (unit.CurrentAnim == "DIE")
                {
                    if (unit.DeadTime >= 120)
                    {
                        if (unit.Fade == 1)
                            this.PeonList.RemoveAt(index1);
                        else
                            unit.Fade -= 2;
                    }
                    else
                        unit.DeadTime++;
                }
            }
        }
        #endregion

        #region upgrade

        //Researchs Upgrades
        public void UpgradeTitanium()
        {
            for (int i = 2; i < 5; i++)
            {
                UnitexploResist[i] += 5;
                UnitprojeResist[i] += 5;
                UnitsliceResist[i] += 5;
            }
        }
        public void UpgradeGauss()
        {
            UnitPower[2] *= 1.2;
            UnitPower[4] *= 1.2;
        }
        public void UpgradeNeutronium()
        {
            for (int i = 6; i < 9; i++)
            {
                UnitexploResist[i] += 5;
                UnitprojeResist[i] += 5;
                UnitsliceResist[i] += 5;
            }
        }
        public void UpgradeEngine()
        {
            for (int i = 6; i < 8; i++)
                UnitSpeed[i] *= 1.2;
        }

        //UPGRADE DE BASE
        public virtual void UpgradeProductionLevel()
        {
            Tools.BankManage(this, -(int)(ProductionLevel * ProductionLevel * (character == Perso.Frohman ? 100 : 200)));
            ProductionLevel++;
            for (int i = 0; i < UnitCost.Length; i++)
            {
                UnitCost[i] -= (5 * (int)(1 + i / 3));
                UnitCost[i] = UnitCost[i] >= 0 ? UnitCost[i] : 0;
            }
            GameSound.baseUpSound.Play();
        }

        public virtual void UpgradeBaseArmor()
        {
            Tools.BankManage(this, -(BaseHealthLevel * BaseHealthLevel * (character == Perso.Frohman ? 50 : 100)));
            BaseHealthLevel++;
            BaseHealth = (BaseHealth * BaseHealthLevel) / (BaseHealthLevel - 1);
            MaxBaseHealth = (MaxBaseHealth * BaseHealthLevel) / (BaseHealthLevel - 1);
            GameSound.baseUpSound.Play();

            if (BaseHealthLevel == 4 && Type == PlayerType.Player)
                AchievementManager.AchievementList[14].Add();
        }

        public void UpgradeIncome()
        {
            Tools.BankManage(this, -(int)(IncomeLevel * 150));
            IncomeLevel++;
            GameSound.baseUpSound.Play();
        }

        //UPGRADE POUR LES AML UNITE
        // Renvoi vrai si la derniere upgrade vien d'etre acheter
        public bool Upgrade(int layernumber, int SkillUpGrade)
        {
            int initialCost = Cost[layernumber, SkillUpGrade];
            int finaleCost = initialCost;
            if (amlBonus)
                finaleCost -= (int)(initialCost * 25 / 100);
            if (character == Perso.Rengar)
                finaleCost -= (int)(initialCost * 10 / 100);
            Tools.BankManage(this, -finaleCost);
            switch (SkillUpGrade)
            {
                case 0:
                    TechPower[layernumber]++;
                    for (int i = layernumber * 3; i < (layernumber * 3) + 3; i++)
                        UnitPower[i] = UnitPower[i] * (1 + ((double)TechPower[layernumber] - 1) / 5);
                    if (TechPower[layernumber] >= 4)
                        return true;
                    Cost[layernumber, SkillUpGrade] *= 3;
                    break;
                case 1:
                    TechAccuracy[layernumber]++;
                    if (TechAccuracy[layernumber] >= 4)
                        return true;
                    Cost[layernumber, SkillUpGrade] *= 2;
                    break;
                case 2:
                    TechResist[layernumber]++;
                    if (TechResist[layernumber] == 4 && Type == PlayerType.Player)
                        AchievementManager.AchievementList[18].Add();
                    UnitResist[layernumber] = (TechResist[layernumber] * TechResist[layernumber] - 1) * 2;
                    if (TechResist[layernumber] >= 4)
                        return true;
                    Cost[layernumber, SkillUpGrade] *= 3;
                    break;
                case 3:
                    TechSpeed[layernumber]++;
                    for (int i = layernumber * 3; i < (layernumber * 3) + 3; i++)
                        UnitSpeed[i] = UnitSpeed[i] * (1.15 + ((double)TechSpeed[layernumber] - 1) / 10);
                    if (TechSpeed[layernumber] >= 4)
                        return true;
                    Cost[layernumber, SkillUpGrade] *= 2;
                    break;
            }
            return false;
        }
        #endregion

        #region pouvoirs
        public virtual void LaunchPower(Power power, User enemyplayer, int seed)
        {
            switch (power)
            {
                case Power.EnergyDrainer: Power_Drain(enemyplayer); break;
                case Power.Heal: Power_Heal(); break;
                case Power.Bombe: Power_Bomb(enemyplayer, seed); break;
                case Power.Cresus: Power_Cresus(); break;
                case Power.SuperPeon: Power_SuperPeon(); break;
            }
        }
        public virtual void Power_Heal()
        {
            foreach (Unit u in PeonList)
            {
                if (u.UnitType != 10)
                {
                    if (u.Health < u.MaxHealth)
                    {
                        if (u.Health < 0.10 * u.MaxHealth && Type == PlayerType.Player)
                            AchievementManager.AchievementList[15].Add();
                        u.Health = u.MaxHealth;
                        User.AdvertList.Add(new Advert(new Vector2(u.Position.X - 5, u.Position.Y - 45), GameData.Font_Pause, "+", 1.3f, new Vector2(0, -1), 1.8f, u.TeamColor, true, false));
                        User.AdvertList.Add(new Advert(new Vector2(u.Position.X - 13, u.Position.Y - 50), GameData.Font_Menu, "+", 1.5f, new Vector2(0, -1), 1.0f, u.TeamColor, true, false));
                        User.AdvertList.Add(new Advert(new Vector2(u.Position.X + 3, u.Position.Y - 45), GameData.Font_Pause, "+", 1.2f, new Vector2(0, -1), 1.5f, u.TeamColor, true, false));
                        User.AdvertList.Add(new Advert(new Vector2(u.Position.X, u.Position.Y - 40), GameData.Font_Menu, "+", 1f, new Vector2(0, -1), 1.6f, u.TeamColor, true, false));
                    }
                }
            }
            GameSound.SoundPouvoirs[0].Play(0.35f, 0, 0);
        }

        public void Power_Bomb(User enemyPlayer, int seed)
        {
            Game.boom = 20f;
            Game.boolbomb = true;
            IsLaunchingBomb = true;
            BombSeed = seed;
        }

        public void Power_BombDamaging(User enemyPlayer)
        {
            IsLaunchingBomb = false;
            DelayAfterLaunching = 0;

            //GameSound.SoundPouvoirs[2].Play(0.35f, 0, 0);
            Random rand = new Random(BombSeed);

            User.EffectList.Add(new AnimatedEffect(Game.Bombes.Position.X - 280, 330, true, GameTexture.TextureEffects[2], 90, 111, 20));
            User.EffectList.Add(new AnimatedEffect(Game.Bombes.Position.X - 160, 330, false, GameTexture.TextureEffects[2], 90, 111, 20));
            User.EffectList.Add(new AnimatedEffect(Game.Bombes.Position.X - 20, 330, false, GameTexture.TextureEffects[2], 90, 111, 20));
            User.EffectList.Add(new AnimatedEffect(Game.Bombes.Position.X + 120, 330, true, GameTexture.TextureEffects[2], 90, 111, 20));
            User.EffectList.Add(new AnimatedEffect(Game.Bombes.Position.X + 280, 330, false, GameTexture.TextureEffects[2], 90, 111, 20));

            User.EffectList.Add(new AnimatedEffect(Game.Bombes.Position.X - 400, 380, false, GameTexture.TextureEffects[1], 62, 63, 3));
            User.EffectList.Add(new AnimatedEffect(Game.Bombes.Position.X - 320, 380, false, GameTexture.TextureEffects[1], 62, 63, 3));
            User.EffectList.Add(new AnimatedEffect(Game.Bombes.Position.X - 200, 380, true, GameTexture.TextureEffects[1], 62, 63, 3));
            User.EffectList.Add(new AnimatedEffect(Game.Bombes.Position.X + 200, 380, false, GameTexture.TextureEffects[1], 62, 63, 3));
            User.EffectList.Add(new AnimatedEffect(Game.Bombes.Position.X + 420, 380, false, GameTexture.TextureEffects[1], 62, 63, 3));
            User.EffectList.Add(new AnimatedEffect(Game.Bombes.Position.X + 500, 380, true, GameTexture.TextureEffects[1], 62, 63, 3));

            int victims = 0;
            foreach (Unit Peon in enemyPlayer.PeonList)
            {
                int dmg = rand.Next(500) + 100; // 100
                if (bombBonus)
                    dmg += rand.Next(500);
                Peon.Health -= dmg;
                if (Peon.DeadTime > 0)
                    victims++;
            }
            if (this.Type == PlayerType.Player)
            {
                if (victims >= 3)
                    AchievementManager.AchievementList[3].Add();
                while (victims > 0)
                {
                    AchievementManager.AchievementList[1].Add();
                    victims--;
                }
            }
            foreach (Unit Peon in this.PeonList)
            {
                int dmg = rand.Next(250) + 100;
                if (bombBonus)
                    dmg += rand.Next(250);
                Peon.Health -= dmg;
            }
        }


        public void Power_Cresus()
        {
            if (Type == PlayerType.Player)
            {
                User.AdvertList.Add(new Advert(new Vector2(140, 440), GameData.Font_Pause, "$", 1.5f, new Vector2(1, 0.2f), 0.2f, Color.Wheat, false, false));
                User.AdvertList.Add(new Advert(new Vector2(140, 440), GameData.Font_Pause, "$", 1.2f, new Vector2(0.8f, 1), 0.56f, Color.Wheat, false, false));
                User.AdvertList.Add(new Advert(new Vector2(140, 440), GameData.Font_Pause, "$", 1.3f, new Vector2(-1, 0), 0.4f, Color.Wheat, false, false));
                User.AdvertList.Add(new Advert(new Vector2(140, 440), GameData.Font_Pause, "$", 1.7f, new Vector2(0, -1), 0.54f, Color.Wheat, false, false));
                User.AdvertList.Add(new Advert(new Vector2(140, 440), GameData.Font_Pause, "$", 1.5f, new Vector2(1, 2.8f), 0.55f, Color.Wheat, false, false));
                User.AdvertList.Add(new Advert(new Vector2(140, 440), GameData.Font_Pause, "$", 1f, new Vector2(2.2f, 1), 0.3f, Color.Wheat, false, false));
                User.AdvertList.Add(new Advert(new Vector2(140, 440), GameData.Font_Pause, "$", 2.0f, new Vector2(-1, 2), 0.5f, Color.Wheat, false, false));
                User.AdvertList.Add(new Advert(new Vector2(140, 440), GameData.Font_Pause, "$", 1.2f, new Vector2(2, -1), 0.4f, Color.Wheat, false, false));
                User.AdvertList.Add(new Advert(new Vector2(140, 440), GameData.Font_Pause, "$", 1.1f, new Vector2(1, 3), 0.4f, Color.Wheat, false, false));
                User.AdvertList.Add(new Advert(new Vector2(140, 440), GameData.Font_Pause, "$", 1.8f, new Vector2(0.7f, 1), 0.5f, Color.Wheat, false, false));
                User.AdvertList.Add(new Advert(new Vector2(140, 440), GameData.Font_Pause, "$", 2.0f, new Vector2(-1, 0.5f), 0.2f, Color.Wheat, false, false));
                User.AdvertList.Add(new Advert(new Vector2(140, 440), GameData.Font_Pause, "$", 1.6f, new Vector2(0.9f, -1), 0.3f, Color.Wheat, false, false));
                GameSound.cashSound.Play(0.35f, 0, 0);
            }
            Tools.BankManage(this, Bank);
        }

        public virtual void Power_Drain(User enemyPlayer)
        {
            if (enemyPlayer.Cooldown < 5)
                AchievementManager.AchievementList[24].Add();
            if (enemyPlayer.Cooldown > 0)
            {
                this.Cooldown += enemyPlayer.Cooldown;
                enemyPlayer.Cooldown = 0;
            }
            else
                this.Cooldown += 10;
            if (this.Cooldown > 100)
                this.Cooldown = 100;

            GameSound.SoundPouvoirs[1].Play(0.35f, 0, 0);
        }

        public void Power_SuperPeon()
        {
            UnitLight3 SuperUnit = new UnitLight3(this);
            SuperUnit.UnitType = 10;
            SuperUnit.Cost = 0;
            SuperUnit.Power += 50;
            SuperUnit.Range += 25;
            SuperUnit.OverallResistance += 30;
            SuperUnit.Energy = 0;
            SuperUnit.MaxHealth = 1200;
            SuperUnit.Health = 1200;
            SuperUnit.AtkType = DamageType.Generic;
            SuperUnit.drawingColor = Color.Silver;
            SpawnUnit(SuperUnit);
        }
        #endregion

        #region divers
        public virtual void Kill(User playerenemy)
        {
            if (PeonList.Count > 0 && !PeonList[0].damaged && PeonList[0].DeadTime == 0)
            {
                PeonList[0].Health = -1;
                if (Type == PlayerType.Player)
                    AchievementManager.AchievementList[19].Add();
                if (PeonList.Count > 1)
                    PeonList[1].SetBaseSpeed();

                // Au cas ou, on est jamais trop prudent
                foreach (Unit Peon in playerenemy.PeonList)
                    if (Peon.State == UnitState.Fire || Peon.State == UnitState.DrawIn)
                    {
                        Peon.AnimationDrawOut();
                        Peon.State = UnitState.DrawOut;
                    }
            }
        }

        public void SetSpawnPosition(int maplength)
        {
            if (TeamBlue)
                this.SpawnPosition = new Vector2(-20, 380);
            else
                this.SpawnPosition = new Vector2(maplength + 20, 380);
        }

        public virtual void Play(User enemy)
        {
            // Permet au joueur de spawner si la derniere unite de sa liste 
            // est a une distance suffisante de sa base.
            if (PeonList.Count > 0 && PeonList[PeonList.Count - 1].CurrentAnim != "DIE")
            {
                if (TeamBlue)
                    CanSpawn = (PeonList[PeonList.Count - 1].Position.X > SpawnPosition.X + 92);
                else
                    CanSpawn = (PeonList[PeonList.Count - 1].Position.X < SpawnPosition.X - 92);
            }
            else
                CanSpawn = true;

            // Sort le peon du buffer si la vois est libre
            if (CanSpawn && PeonBuffer.Count > 0)
            {
                Unit unit = PeonBuffer.Dequeue();
                AddUnitToList(unit);
                PeonBufferDisplay.RemoveAt(0);
                for (int i = 0; i < PeonBufferDisplay.Count; i++)
                {
                    PeonBufferDisplay[i].Position = new Vector2(975 + (15 * i), PeonBufferDisplay[i].Position.Y);
                }
                CanSpawn = false;
            }
        }

        public virtual void AddUnitToList(Unit peonCreated)
        {
            this.PeonList.Add(peonCreated);
            if (!isIA)
                switch (peonCreated.UnitType)
                {
                    case (1):
                        peonCreated.PlaySound(0, 0.5f); break;
                    case (2):
                        peonCreated.PlaySound(0, 0.5f); break;
                    case (3):
                        peonCreated.PlaySound(0, 0.5f); break;
                    case (4):
                        peonCreated.PlaySound(0, 0.5f); break;
                    case (5):
                        peonCreated.PlaySound(0, 0.2f); break;
                    case (6):
                        peonCreated.PlaySound(0, 0.2f); break;
                    case (7):
                        peonCreated.PlaySound(0, 0.2f); break;
                    case (8):
                        peonCreated.PlaySound(0, 0.4f); break;
                    case (9):
                        peonCreated.PlaySound(0, 0.2f); break;
                }
        }

        public virtual void SpawnUnit(Unit peonCreated)
        {
            if (CanSpawn) // Spawn direct le peon
            {
                AddUnitToList(peonCreated);
            }
            else // L'ajoute au buffer
            {
                addPeonToBuffer(peonCreated);
            }

            this.Cooldown -= Energy[peonCreated.UnitType - 1];
            if (Type == PlayerType.Player && peonCreated.UnitType == 3)
                AchievementManager.AchievementList[22].Add();
            Tools.BankManage(this, -peonCreated.Cost);
            if (Type == PlayerType.Player)
                GameSound.cashSound.Play(0.3f, 0f, 0f);
        }

        public void addPeonToBuffer(Unit Peon)
        {
            this.PeonBuffer.Enqueue(Peon);
            this.PeonBufferDisplay.Add(new Sprite(975 + (15 * PeonBufferDisplay.Count), 615, GameTexture.TextureMinimap[(Peon.UnitType - 1) / 3], TeamColor));
            if (Type == PlayerType.Player && PeonBuffer.Count > 3)
                AchievementManager.AchievementList[23].Add();
        }

        private void DoktorPower()
        {
            foreach (Unit peon in PeonList)
            {
                if (peon.UnitType < 7)
                {
                    if (peon.damaged && (peon.CurrentAnim == "WALK" || peon.CurrentAnim == "IDLE"))
                        peon.Health += 0.5;
                    if (peon.MaxHealth <= peon.Health)
                        peon.damaged = false;
                }
            }
        }

        public void UnlockPower()
        {
            int index = Level - 1;
            for (int i = 0; i < PowersList.Length; i++)
                if (i <= index)
                    PowersList[i].Available = true;
                else
                    PowersList[i].Available = false;
        }
        #endregion
    }
}
